package com.scs.application.modules.sys.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.core.mvc.controller.CrudController;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.query.QueryContextHolder;
import com.scs.application.core.utils.FileUtils;
import com.scs.application.core.utils.IPUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UtilCommon;
import com.scs.application.modules.cfg.utils.ParameterUtils;
import com.scs.application.modules.sys.entity.Log;
import com.scs.application.modules.sys.mapper.LogMapper;
import com.scs.application.modules.sys.model.PageResult;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.sys.properties.SystemProperties;
import com.scs.application.modules.sys.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 */
@RestController
@RequestMapping("/sys/log")
public class LogController extends CrudController<LogService, Log>{
    @Autowired
    private SystemProperties systemProperties;
    @Autowired
    @Lazy
    private LogMapper logMapper;
    /**
     * @Description： 获取日志目录
     */
    @GetMapping(value = "/getLogFiles")
    public RestResult getLogFiles(String name,String type,String year) {
        File file = new File(systemProperties.getLogpath());
        if (file ==null || !file.exists()) return null;
        File[] tempList = file.listFiles();
        name= UtilCommon.getStr(name,"");
        type= UtilCommon.getStr(type,"");
        year= UtilCommon.getStr(year,"");

        Map<String,String> fileMap;
        List<Map<String,String>> fileMapList = new ArrayList<Map<String,String>>();
        String logType;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < tempList.length; i++) {
            file = tempList[i];

            fileMap = new HashMap();
            fileMap.put("name",file.getName());
            fileMap.put("path",file.getName());
            logType = "debug";
            if (file.getName().contains("info")) logType = "info";
            else if (file.getName().contains("error")) logType = "error";
            else if (file.getName().contains("warn")) logType = "warn";



            fileMap.put("type",logType);
            //不能直接进行运算，会损失精度,因此先取得大小
            double fileSize = file.length();
            //转换单位为MB
            double fileSizeMB = new BigDecimal(fileSize/1024/1024).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            fileMap.put("size",fileSizeMB+"");
            fileMap.put("lastModified",sdf.format(file.lastModified()));
            fileMap.put("isDir",file.isDirectory() ? "1" : "0");

            //过滤日志类型
            if (StringUtils.isNotBlank(type) && !type.equals(logType)) continue;

            //过滤年份
            if (StringUtils.isNotBlank(year) && !year.equals(fileMap.get("lastModified").substring(0,4))) continue;

            //过滤文件名
            if (StringUtils.isNotBlank(name) && file.getName().indexOf(name) == -1) continue;

            fileMapList.add(fileMap);
        }

        return RestResult.ok("操作成功", fileMapList);
    }

    /**
     * 下载日志文件
     * @param response
     */
    @RequestMapping("downLogFile")
    @ResponseBody
    public void downLogFile(HttpServletResponse response,String fileName) {
        File path = null;
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
        } catch (UnsupportedEncodingException e2) {
            e2.printStackTrace();
        }
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            path = new File(ResourceUtils.getURL("classpath:").getPath());
            os = response.getOutputStream();
            File file = new File(systemProperties.getLogpath()+"/"+fileName);
            bis = new BufferedInputStream(new FileInputStream(file));
            int i = bis.read(buff);
            while (i != -1) {
                os.write(buff, 0, buff.length);
                os.flush();
                i = bis.read(buff);
            }
        } catch (FileNotFoundException e1) {
            //e1.getMessage()+"系统找不到指定的文件";
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取日志文件内容
     */
    @RequestMapping("getLogFileText")
    @ResponseBody
    public RestResult getLogFileText(String fileName) {
        File file = new File(systemProperties.getLogpath()+"/"+fileName);
        List<String> lines = null;
        try {
            lines = FileUtils.readLines(file,"utf-8");
        } catch (IOException e) {
            logger.error("LogController.getLogFileText",e);
            return  RestResult.ok("获取日志文件内容失败，原因："+e.getMessage());
        }
        return RestResult.ok("获取日志文件内容成功", lines);
    }

    /**
     * 返回SystemProperties里面某些属性给前端使用
     */
    @RequestMapping("getSystemProperties")
    @ResponseBody
    public RestResult getSystemProperties(HttpServletRequest request) {
        Map<String,Object> map = new HashMap<String,Object>();
        if (systemProperties != null) {
            map.put("flagProject",systemProperties.getFlagProject());
        }
        map.put("versionApi", GlobalConsts.VERSION_API);
        map.put("customIp", IPUtils.getIpAddr(request));
        map.put("hospital", systemProperties.getHospital());
        return RestResult.ok("获取成功", map);
    }


    /**
     * @Description： 获取备份列表
     */
    @GetMapping(value = "/getDbbackData")
    public RestResult getDbbackData() {
        String systemDbbackPath = ParameterUtils.getSystemDbbackPath();
        RestResult restResult =RestResult.ok();
        if (StringUtils.isBlank(systemDbbackPath)) {
            return RestResult.error("获取数据失败，系统参数【system_dbback_path】不存在");
        }
        File file = new File(systemDbbackPath);
        if (file ==null || !file.exists()) {
            return RestResult.error(String.format("获取数据失败，系统参数【system_dbback_path】指定的路径【%s】不存在",systemDbbackPath));
        };
        File[] tempList = file.listFiles();
        if (tempList ==null || tempList.length < 1) {
            return RestResult.error(String.format("获取数据失败，系统参数【system_dbback_path】指定的路径【%s】没有任何备份文件",systemDbbackPath));
        };

        Map<String,String> fileMap;
        List<Map<String,String>> fileMapList = new ArrayList<Map<String,String>>();
        String logType;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < tempList.length; i++) {
            file = tempList[i];
            if (file.isDirectory()) continue;
            fileMap = new HashMap();
            fileMap.put("name",file.getName());
            fileMap.put("path",file.getAbsolutePath());

            //不能直接进行运算，会损失精度,因此先取得大小
            double fileSize = file.length();
            //转换单位为MB
            double fileSizeMB = new BigDecimal(fileSize/1024/1024).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            fileMap.put("size",fileSizeMB+"");
            fileMap.put("lastModified",sdf.format(file.lastModified()));
            fileMap.put("isDir",file.isDirectory() ? "1" : "0");
            fileMapList.add(fileMap);
        }
        if (fileMapList.size() < 1) {
            return RestResult.error("获取数据失败，系统参数【system_dbback_path】指定的路径【%s】没有任何备份文件", systemDbbackPath);
        };

        //日期倒序
        fileMapList.sort(Comparator.comparing((Map<String, String> h) -> (h.get("lastModified"))).reversed());
        return RestResult.ok("操作成功", fileMapList);
    }


    //获取系统日志业务类型
    @GetMapping("/getBusTypeList")
    public RestResult<List> list() {
        QueryContext queryContext = QueryContextHolder.currentContext();
        Map<String, Object> mapParam = queryContext.getParams();
        QueryWrapper queryWrapper = Wrappers.<Log>query();
        queryWrapper.select("bus_type as value,bus_type as label");
        queryWrapper.groupBy("bus_type");
        queryWrapper.isNotNull("bus_type");
        queryWrapper.orderByAsc("bus_type");
        List<Map<String, Object>> list = service.listMaps(queryWrapper );
        if (list == null) {
            list = new ArrayList<>();
        }
        Map<String, Object> map = new HashMap<>();
        map.put("label", "未指定业务");
        map.put("value", "");
        list.add(0,map);
        return RestResult.ok("查询成功", list);
    }



    /**
     * 定时任务日志查看
     */
    @GetMapping("/pageJob")
    public PageResult pageJob(@RequestParam Map<String, Object> reqData) {
        Map<String, Object> userParam = null;

        if (reqData.containsKey("userParam")) {
            JSONObject ob = JSON.parseObject(reqData.get("userParam") + "");
            userParam = Maps.newHashMap(ob);
        }else {
            userParam = new HashMap<>();
        }
        QueryContext queryContext = QueryContextHolder.currentContext();

        IPage pageResult = logMapper.pageJob(queryContext.getPage(), queryContext.getWrapper(), userParam);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }
}
